<?php

namespace UtilMethod;

define("RSA_MAX_ORIGINAL", 117); //RSA明文分段最大长度
define("RSA_MAX_CIPHER", 256); //RSA密文分段最大长度

class Utils {

    /**
     * 发送post请求 
     * @param string $url 请求地址 
     * @param array $post_data post键值对数据 
     * @return string 
     */
    public static function send_post($url, $post_data) {
        $postdata = http_build_query($post_data);
        $options = array(
            'http' => array(
                'method' => 'POST',
                'header' => 'Content-type:application/x-www-form-urlencoded',
                'content' => $postdata,
                'timeout' => 30 * 60 // 超时时间（单位:s）  
            )
        );
        $context = stream_context_create($options);
        $result = file_get_contents($url, false, $context);

        return $result;
    }

    public static function send_post1($url = '', $post_data = '') {
        if (empty($url) || empty($post_data)) {
            return false;
        }
        $postUrl = $url;
        $curlPost = $post_data;
        $ch = curl_init(); //初始化curl
        curl_setopt($ch, CURLOPT_URL, $postUrl); //抓取指定网页
        curl_setopt($ch, CURLOPT_HEADER, 0); //设置header
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
        $data = curl_exec($ch); //运行curl
        curl_close($ch);
        return $data;
    }

    /**
     * RSA公钥加密(分段加密)
     * @param type $data
     * @param type $keyPath
     * @return type
     */
    public static function rsaPublicEncrypt($data, $keyPath) {
        $key = openssl_pkey_get_public(file_get_contents($keyPath));
        $ciphertext = null;
        $cipher_len = strlen($data);
        if ($cipher_len - RSA_MAX_ORIGINAL > 0) {
            $flag = 0;
            for ($i = ceil($cipher_len / RSA_MAX_ORIGINAL); $i > 0; $i--) {
                $temp = substr($data, $flag, RSA_MAX_ORIGINAL);
                $r = openssl_public_encrypt($temp, $encryptData, $key);
                $ciphertext.=$encryptData;
                if ($r) {
                    $flag+=RSA_MAX_ORIGINAL;
                } else {
                    print("RSA分段加密失败.");
                }
            }
        } else {
            $r = openssl_public_encrypt($data, $encryptData, $key);
            if ($r) {
                $ciphertext = $encryptData;
            }
        }
        return base64_encode($ciphertext);
    }

    /**
     * RSA私钥解密(分段解密)
     * @param type $data
     * @param type $keyPath
     */
    public static function rsaPrivateDecrypt($data, $keyPath) {
        $key = openssl_pkey_get_private(file_get_contents($keyPath));
        $originalText = null;
        $original_len = strlen($data);
        if ($original_len - RSA_MAX_CIPHER > 0) {
            $flag = 0;
            for ($i = ceil($original_len / RSA_MAX_CIPHER); $i > 0; $i--) {
                $temp = substr($data, $flag, RSA_MAX_CIPHER);
                $r = openssl_private_decrypt($temp, $decrypted, $key);
                $originalText.=$decrypted;
                if ($r) {
                    $flag+=RSA_MAX_CIPHER;
                } else {
                    print("RSA分段解密失败.");
                }
            }
        } else {
            $r = openssl_private_decrypt($data, $decrypted, $key);
            if ($r) {
                $originalText = $decrypted;
            }
        }
        return base64_decode($originalText);
    }
    
    /**
     * 数据签名
     * @param type $data
     * @param type $keyPath
     * @return boolean
     */
    public static function rsaDataSign($data, $keyPath) {
        
        if (empty($data)) {
            return False;
        }

        $private_key = file_get_contents($keyPath);
        if (empty($private_key)) {
            echo "Private Key error!";
            return False;
        }

        $pkeyid = openssl_get_privatekey($private_key);
        if (empty($pkeyid)) {
            echo "private key resource identifier False!";
            return False;
        }

        $verify = openssl_sign($data, $signature, $pkeyid, OPENSSL_ALGO_MD5);
        openssl_free_key($pkeyid);
        return base64_encode($signature);
    }

   /**
    * 数据验签
    * @param type $data
    * @param type $signature
    * @param type $keyPath
    * @return boolean
    */
    public static function isValid($data = '', $signature = '', $keyPath) {
        if (empty($data) || empty($signature)) {
            return False;
        }

        $public_key = file_get_contents($keyPath);
        if (empty($public_key)) {
            echo "Public Key error!</br>";
            return False;
        }

        $pkeyid = openssl_get_publickey($public_key);
        if (empty($pkeyid)) {
            echo "public key resource identifier False!</br>";
            return False;
        }

        $ret = openssl_verify($data, $signature, $pkeyid, OPENSSL_ALGO_MD5);
        switch ($ret) {
            case -1:
                echo "error</br>";
                break;
            default:
                echo $ret == 1 ? "验签成功" : "验签失败"; //0:incorrect
                echo "</br>";
                break;
        }
        return $ret;
    }

    public static function hexStrToBytes($str, $length = null) {
        $ret = ['c*'];
        for ($i = 0, $l = strlen($str) / 2; $i < $l; ++$i) {
            $x = intval(substr($str, 2 * $i, 2), 16);
            if ($x > 128)
                $x -= 256;
            $ret[] = $x;
        }
        //补全24位
        if (isset($length)) {
            for ($i = count($ret), $j = 1; $i <= $length; ++$i, ++$j)
                $ret[] = $ret[$j];
        }
        return call_user_func_array('pack', $ret);
    }

}
